package com.example.novelweb.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.novelweb.common.BaseResponse;
import com.example.novelweb.common.ErrorCode;
import com.example.novelweb.common.ResultUtils;
import com.example.novelweb.constant.CommonConstant;
import com.example.novelweb.exception.BusinessException;
import com.example.novelweb.exception.ThrowUtils;
import com.example.novelweb.mapper.CommentMapper;
import com.example.novelweb.model.dto.comment.CommentAddRequest;
import com.example.novelweb.model.dto.comment.CommentQueryRequest;
import com.example.novelweb.model.entity.Comment;
import com.example.novelweb.model.vo.CommentVO;
import com.example.novelweb.model.vo.UserVO;
import com.example.novelweb.service.CommentService;
import com.example.novelweb.service.UserService;
import com.example.novelweb.utils.SqlUtils;
import com.example.novelweb.utils.UserUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
* @author PERSON
* @description 针对表【comment(用户评论)】的数据库操作Service实现
* @createDate 2025-02-01 19:00:08
*/
@Service
public class CommentServiceImpl extends ServiceImpl<CommentMapper, Comment>
    implements CommentService{

  @Resource
  private UserService userService;


  @Override
  public BaseResponse<Page<CommentVO>> pageCommentByNovelId(CommentQueryRequest commentQueryRequest) {
    Page<CommentVO> page = pageAllRootByNovelId(commentQueryRequest);
    for(CommentVO vo : page.getRecords()) {
      List<CommentVO> replies = listChildrenByTopId(vo.getId()
          , commentQueryRequest.getSortField(), commentQueryRequest.getSortOrder());
      vo.setReplies(replies);
    }

    return ResultUtils.success(page);
  }

  @Override
  public void updateLikesByAdd(Long commentId, Long curNum) {
    // get like Num
    Comment comment = lambdaQuery().select(Comment::getLikes)
        .eq(Comment::getId,commentId).one();
    ThrowUtils.throwIf(comment == null,ErrorCode.OPERATION_ERROR);
    Long likes = comment.getLikes();

    // update likes  = likes + curNum
    boolean ret = lambdaUpdate().eq(Comment::getId,commentId)
        .set(Comment::getLikes,likes+curNum)
        .update();
    ThrowUtils.throwIf(!ret,ErrorCode.OPERATION_ERROR);
  }

  @Override
  public BaseResponse<Long> add(CommentAddRequest commentAddRequest) {
    // 校验已登录
    UserVO userVO = UserUtils.LoginCheck();
    if( userVO== null) {
      throw new BusinessException(ErrorCode.NOT_LOGIN_ERROR,"用户未登录");
    }
    // 校验 ids
    long topId = commentAddRequest.getTopId();
    long parentId = commentAddRequest.getParentId();
    if((topId == 0 && parentId !=0) || (topId != 0 && parentId ==0 )) {
      throw new BusinessException(ErrorCode.PARAMS_ERROR,"id params invalid");
    }
    long replierId = commentAddRequest.getReplierId();
    if(topId != 0) {
      if(parentId == topId) {
        ThrowUtils.throwIf(replierId != 0,ErrorCode.PARAMS_ERROR,"id params invalid");
      } else {
        ThrowUtils.throwIf(replierId <= 0,ErrorCode.PARAMS_ERROR,"id params invalid");
      }
    }
    // 校验 content
    String content = commentAddRequest.getContent();
    // 1024/3 =341
    if(content.length() > 300) {
      throw new BusinessException(ErrorCode.PARAMS_ERROR, "评论字数过长(>300)");
    }
    Long userId = userVO.getId();
    Comment comment = new Comment();
    BeanUtils.copyProperties(commentAddRequest,comment);
    comment.setUserId(userId);

    boolean result  = save(comment);
    ThrowUtils.throwIf(!result,ErrorCode.OPERATION_ERROR);
    return ResultUtils.success(comment.getId());
  }

  @Override
  public BaseResponse<Boolean> del(Long commentId) {
    // 校验已登录
    UserVO userVO = UserUtils.LoginCheck();
    if( userVO== null) {
      throw new BusinessException(ErrorCode.NOT_LOGIN_ERROR,"用户未登录");
    }
    // TODO: 权限检测:admin / user
    boolean result = removeById(commentId);
    ThrowUtils.throwIf(!result,ErrorCode.OPERATION_ERROR);
    return ResultUtils.success(true);
  }

// private functions:

  private Page<CommentVO> pageAllRootByNovelId(CommentQueryRequest commentQueryRequest) {
    Long novelId = commentQueryRequest.getNovelId();

    String sortField = commentQueryRequest.getSortField();
    String sortOrder = commentQueryRequest.getSortOrder();
    int current = commentQueryRequest.getCurrent();
    int pageSize = commentQueryRequest.getPageSize();

    QueryWrapper<CommentVO> queryWrapper = new QueryWrapper<>();
    queryWrapper.orderBy(SqlUtils.validSortField(sortField),
        sortOrder.equals(CommonConstant.SORT_ORDER_ASC), sortField);
    queryWrapper.eq("c.novelId",novelId).eq("c.parentId",0).eq("c.isDelete",0);

    return getBaseMapper().pageAllRootByNovelId(new Page<>(current,pageSize),queryWrapper);
  }

  private List<CommentVO> listChildrenByTopId(Long topId,String sortField,String sortOrder) {
    List<Comment> comments = query().eq("topId",topId)
        .orderBy(SqlUtils.validSortField(sortField),sortOrder.equals(CommonConstant.SORT_ORDER_ASC), sortField)
        .list();
    List<CommentVO> children = new ArrayList<>();


    // get UserVO : user,replier
    for(Comment c:comments) {
      CommentVO commentVO = new CommentVO();
      BeanUtils.copyProperties(c,commentVO);

      commentVO.setUser(userService.getVOById(c.getUserId()));
      Long replierId = c.getReplierId();
      if(replierId != 0) {
        commentVO.setReplier(userService.getVOById(replierId));
      }
      children.add(commentVO);
    }

    return children;
  }


}




